Skip to content

fix(ui): resolve metadata agent form crash and manifest JSON editor UX#30141

Merged
aniketkatkar97 merged 11 commits into
mainfrom
s3-widget-error-metadata-agent
Jul 20, 2026
Merged

fix(ui): resolve metadata agent form crash and manifest JSON editor UX#30141
aniketkatkar97 merged 11 commits into
mainfrom
s3-widget-error-metadata-agent

Conversation

@aniketkatkar97

@aniketkatkar97 aniketkatkar97 commented Jul 16, 2026

Copy link
Copy Markdown
Member

Fixes #30142

Problem

Adding or editing a metadata agent for a Storage (S3) service crashed the UI:

Error: Unsupported widget definition: object
    at getWidget (@rjsf/utils)

IngestionWorkflowForm registers its RJSF widgets as raw React.lazy(...) objects. @rjsf/utils getWidget (v5.24.13) accepts only function / forwardRef / memo / string — a React.lazy result is a plain object, so resolving the storage defaultManifest → ui:widget: 'manifestJson' threw. Introduced by #28569, which switched this form's widgets to React.lazy.

Testing the (now-rendering) Default Manifest editor surfaced three more UX bugs: it was half-width, the caret jumped while typing, and clearing it reverted to the sample JSON.

Changes

Crash fix

  • IngestionWorkflowForm: wrap the lazy RJSF widgets in the existing withSuspenseFallback HOC (returns a forwardRef, which getWidget accepts) so they resolve while keeping code-splitting. Same pattern MetadataAgentsWidget already uses.

Manifest JSON editor

  • Full widthIngestionObjectFieldTemplate.isWide() now treats uiFieldType: 'code' fields as full-row (generic, no hardcoded field name).
  • No caret jumpSchemaEditor gains an autoFormat prop (default true, existing consumers unchanged); ManifestJsonWidget sets autoFormat={false} so the buffer is not re-indented via JSON.stringify on every keystroke.
  • No stale default — the sample manifest is shown as a CodeMirror placeholder (muted --tw-color-text-placeholder, multi-line via pre-wrap, editor flex-fills its wrapper) instead of being written as the field value. Clearing the editor now leaves it truly empty.

Testing

  • Playwright (StorageMetadataAgentForm.spec.ts): edit form renders without crashing, manifest edits save (asserted on the PATCH /services/ingestionPipelines/{id} response) and round-trip on reopen; editor is full width, clears cleanly (placeholder muted + multi-line), and the caret stays stable (no live re-format). Verified end-to-end against a local backend + Airflow.
  • Unit — new SchemaEditor.utils.test.ts covers getSchemaEditorValue (both autoFormat modes + edge cases); ManifestJsonWidget tests updated to the placeholder contract; existing validateManifestJson coverage unchanged. jest → 33 passing.

🤖 Generated with Claude Code

Greptile Summary

This PR fixes the storage metadata-agent form and improves the manifest JSON editor. The main changes are:

  • Wrap lazy RJSF widgets in Suspense-compatible components.
  • Keep manifest JSON input unformatted while typing.
  • Show the sample manifest as a placeholder instead of a field value.
  • Make code fields use the full form width.
  • Add unit and end-to-end tests for the updated workflow.

Confidence Score: 5/5

This looks safe to merge.

  • The previously reported checkstyle failure is fixed.
  • No remaining issue qualifies for this follow-up review.

Important Files Changed

Filename Overview
openmetadata-ui/src/main/resources/ui/src/components/Settings/Services/Ingestion/IngestionWorkflowForm/IngestionWorkflowForm.tsx Wraps lazy widgets so RJSF can resolve and render them.
openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaEditor/SchemaEditor.tsx Adds optional formatting, placeholder support, and an uncontrolled editor mode.
openmetadata-ui/src/main/resources/ui/src/components/common/Form/JSONSchema/JsonSchemaWidgets/ManifestJsonWidget/ManifestJsonWidget.tsx Uses an empty editor value with a sample placeholder and disables live formatting.
openmetadata-ui/src/main/resources/ui/playwright/e2e/Features/StorageMetadataAgentForm.spec.ts Covers rendering, editing, persistence, layout, placeholder behavior, and caret stability.

Reviews (7): Last reviewed commit: "Merge branch 'main' into s3-widget-error..." | Re-trigger Greptile

Context used (3)

  • Context used - CLAUDE.md (source)
  • Context used - openmetadata-ui-core-components/CLAUDE.md (source)
  • Context used - AGENTS.md (source)

The add/edit metadata agent form crashed with "Unsupported widget
definition: object" for Storage (S3) services. IngestionWorkflowForm
registered its RJSF widgets as raw React.lazy objects; @rjsf/utils
getWidget accepts only function/forwardRef/memo, so resolving the
manifestJson widget threw. Wrap the lazy widgets in the existing
withSuspenseFallback (forwardRef) so getWidget accepts them while keeping
code-splitting.

Also fixes the Default Manifest JSON editor:
- Full width: isWide() now treats uiFieldType 'code' fields as wide.
- No caret jump: SchemaEditor gains an autoFormat prop (default true); the
  manifest widget disables it so the buffer is not re-indented on every
  keystroke.
- No stale default: the sample is shown as a CodeMirror placeholder
  (muted --tw-color-text-placeholder, multi-line, editor flex-fills its
  wrapper) instead of being written as the field value.

Adds a Playwright spec (render + edit/save round-trip, width, clears
cleanly, caret stability) and unit tests for getSchemaEditorValue; updates
ManifestJsonWidget tests to the placeholder contract.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:17
@aniketkatkar97
aniketkatkar97 requested a review from a team as a code owner July 16, 2026 12:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added safe to test Add this label to run secure Github workflows on PRs UI UI specific issues labels Jul 16, 2026
@open-metadata open-metadata deleted a comment from github-actions Bot Jul 16, 2026
Copilot AI review requested due to automatic review settings July 16, 2026 12:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@open-metadata open-metadata deleted a comment from github-actions Bot Jul 16, 2026
Satisfies the space-after-comment lint rule flagged in review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 65%
65.1% (75660/116208) 48.88% (45073/92202) 49.7% (13643/27450)

react-codemirror2's Controlled mode cancels CodeMirror's native change and
re-applies the value, which drops the caret that autoCloseBrackets places
between the inserted pair (typing `{` produced `{}` with the caret after `}`,
so the next character landed outside).

Add an opt-in `uncontrolled` mode to SchemaEditor that renders the UnControlled
CodeMirror so the editor owns its buffer and caret. The value prop is used only
as initial content; external updates (e.g. an async-loaded saved config) are
synced imperatively while the editor is blurred so active typing is never
disturbed. ManifestJsonWidget opts in.

Adds a Playwright assertion that typing `{` then `x` yields `{x}`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:52

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Address review edge case: an external value arriving while the uncontrolled
editor is focused was skipped by the blurred-only sync and never re-applied.
Track the latest value and apply it on the next blur.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:57
Copilot AI review requested due to automatic review settings July 17, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 17, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 04:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@sonarqubecloud

Copy link
Copy Markdown

@open-metadata open-metadata deleted a comment from github-actions Bot Jul 20, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🟡 Playwright Results — all passed (27 flaky)

✅ 4547 passed · ❌ 0 failed · 🟡 27 flaky · ⏭️ 95 skipped

Shard Passed Failed Flaky Skipped
🟡 Shard 1 435 0 5 16
✅ Shard 2 11 0 0 0
🟡 Shard 3 824 0 9 8
🟡 Shard 4 819 0 4 18
✅ Shard 5 843 0 0 5
🟡 Shard 6 786 0 2 46
🟡 Shard 7 829 0 7 2
🟡 27 flaky test(s) (passed on retry)
  • Features/DataAssetRulesDisabled.spec.ts › Verify the Directory entity item action after rules disabled (shard 1, 1 retry)
  • Features/Glossary/GlossaryPagination.spec.ts › should filter by InReview status (shard 1, 1 retry)
  • Features/Pagination.spec.ts › should test Database Schema Tables normal pagination (shard 1, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab IS visible for supported type: metric (shard 1, 1 retry)
  • Flow/SearchRBAC.spec.ts › a fully denied user sees neither asset type when browsing (shard 1, 1 retry)
  • Features/BulkImportWithDotInName.spec.ts › Column with dot in name under service with dot (shard 3, 1 retry)
  • Features/BulkImportWithDotInName.spec.ts › Import at schema level with dot in service name (shard 3, 1 retry)
  • Features/ContextCenterArchive.spec.ts › archive page lazy-loads more rows on scroll within its own scroll container (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › Article listing search filters, clears, and shows empty state (shard 3, 1 retry)
  • Features/ContextCenterArticles.spec.ts › description: switching articles does not bleed unsaved content into next article (shard 3, 1 retry)
  • Features/ContextCenterMemories.spec.ts › adding a linked asset in edit mode shows entity badge on the row (shard 3, 1 retry)
  • Features/ContextCenterPermission.spec.ts › user with deleteAll permission can see delete action but not restore action on an archived document, and can delete it (shard 3, 1 retry)
  • Features/Glossary/GlossaryCRUDOperations.spec.ts › should create glossary with mutually exclusive enabled (shard 3, 1 retry)
  • Features/Glossary/GlossaryHierarchy.spec.ts › should move term with children to different glossary (shard 3, 1 retry)
  • Features/Glossary/GlossaryTermRelationsGraphNested.spec.ts › viewing a child term: parent appears as a 1-hop neighbour via parentOf edge (shard 4, 1 retry)
  • Features/MetricBulkImportExportEdit.spec.ts › Admin starts exactly one async export job from the metrics listing (shard 4, 2 retries)
  • Features/MetricBulkImportExportEdit.spec.ts › MetricListPage unchecking header checkbox clears the selection bar (shard 4, 2 retries)
  • Features/SearchExport.spec.ts › Export queues a background job and downloads from the jobs tray (shard 4, 1 retry)
  • Pages/Entity.spec.ts › Announcement create, edit & delete (shard 6, 1 retry)
  • Pages/EntityDataSteward.spec.ts › Tier Add, Update and Remove (shard 6, 1 retry)
  • Pages/ExplorePageRightPanel.spec.ts › Should allow Data Steward to edit tags for dashboardDataModel (shard 7, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Check for Circular Reference in Glossary Import (shard 7, 1 retry)
  • Pages/GlossaryImportExport.spec.ts › Import partial success - some terms pass, some fail (shard 7, 1 retry)
  • Pages/Lineage/LineageFilters.spec.ts › Verify Impact Analysis service filter selection (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for pipelineService in platform lineage (shard 7, 1 retry)
  • Pages/Lineage/LineageRightPanel.spec.ts › Verify custom properties tab is NOT visible for apiService in platform lineage (shard 7, 1 retry)
  • Pages/TestSuite.spec.ts › Logical TestSuite (shard 7, 1 retry)

📦 Download artifacts

How to debug locally
# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip    # view trace

@aniketkatkar97
aniketkatkar97 merged commit 2d759a6 into main Jul 20, 2026
59 checks passed
@aniketkatkar97
aniketkatkar97 deleted the s3-widget-error-metadata-agent branch July 20, 2026 13:16
@gitar-bot

gitar-bot Bot commented Jul 20, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Resolves the metadata agent form crash by wrapping lazy RJSF widgets in suspense fallbacks and improves manifest JSON editor UX with stable caret handling and proper placeholder support. No issues found.

✅ 1 resolved
Edge Case: Uncontrolled sync skips value updates that arrive while focused

📄 openmetadata-ui/src/main/resources/ui/src/components/Database/SchemaEditor/SchemaEditor.tsx:145-153
The uncontrolled-mode sync effect only pushes an external value change into the editor when it is blurred, and it only runs when [value, autoFormat, uncontrolled] change. If a new value (e.g. an async-loaded saved config) arrives while the editor is focused, the effect skips the update and never re-runs on blur, leaving the editor showing stale content. This is a narrow case since the user must already be focused when the async load resolves. If needed, track focus/pending state so the deferred value is applied on the next blur.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

safe to test Add this label to run secure Github workflows on PRs UI UI specific issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S3 metadata agent form crashes: "Unsupported widget definition: object"

3 participants